import asyncio
from typing import Callable, Any, Dict, Optional, List
from robyn import Robyn
import json
from .docs_generator import DocsIntegration


class SimpleApi:
    """基于Robyn的简单API框架"""
    
    def __init__(self, host: str = "127.0.0.1", port: int = 8000, 
                 title: str = "SimpleAPI", version: str = "1.0.0", 
                 description: str = "", docs_url: str = "/api/docs", 
                 redoc_url: str = "/api/redoc", openapi_url: str = "/api/openapi.json",
                 enable_docs: bool = True):
        # 创建Robyn实例，禁用内置OpenAPI功能避免路由冲突
        self.app = Robyn(__file__, openapi_file_path="", openapi=None)
        self.host = host
        self.port = port
        self.enable_docs = enable_docs
        
        # 初始化文档集成
        if enable_docs:
            self.docs = DocsIntegration(
                self, title, version, description, 
                docs_url, redoc_url, openapi_url
            )
        else:
            self.docs = None
    
    def get(self, path: str, summary: str = None, description: str = None, 
            tags: List[str] = None):
        """GET路由装饰器"""
        def decorator(func: Callable):
            async def wrapper(request):
                # 如果原函数是异步的，直接调用
                if asyncio.iscoroutinefunction(func):
                    result = await func()
                else:
                    result = func()
                
                # 如果返回的是字典，转换为JSON响应
                if isinstance(result, dict):
                    return json.dumps(result)
                return result
            
            # 注册路由到Robyn应用
            self.app.get(path)(wrapper)
            
            # 添加到文档
            if self.docs:
                self.docs.add_route_docs(path, "GET", func, summary, description, tags)
            
            return func
        return decorator
    
    def post(self, path: str, summary: str = None, description: str = None,
             tags: List[str] = None):
        """POST路由装饰器"""
        def decorator(func: Callable):
            async def wrapper(request):
                if asyncio.iscoroutinefunction(func):
                    result = await func()
                else:
                    result = func()
                
                if isinstance(result, dict):
                    return json.dumps(result)
                return result
            
            self.app.post(path)(wrapper)
            
            # 添加到文档
            if self.docs:
                self.docs.add_route_docs(path, "POST", func, summary, description, tags)
            
            return func
        return decorator
    
    def put(self, path: str, summary: str = None, description: str = None,
            tags: List[str] = None):
        """PUT路由装饰器"""
        def decorator(func: Callable):
            async def wrapper(request):
                if asyncio.iscoroutinefunction(func):
                    result = await func()
                else:
                    result = func()
                
                if isinstance(result, dict):
                    return json.dumps(result)
                return result
            
            self.app.put(path)(wrapper)
            
            # 添加到文档
            if self.docs:
                self.docs.add_route_docs(path, "PUT", func, summary, description, tags)
            
            return func
        return decorator
    
    def delete(self, path: str, summary: str = None, description: str = None,
               tags: List[str] = None):
        """DELETE路由装饰器"""
        def decorator(func: Callable):
            async def wrapper(request):
                if asyncio.iscoroutinefunction(func):
                    result = await func()
                else:
                    result = func()
                
                if isinstance(result, dict):
                    return json.dumps(result)
                return result
            
            self.app.delete(path)(wrapper)
            
            # 添加到文档
            if self.docs:
                self.docs.add_route_docs(path, "DELETE", func, summary, description, tags)
            
            return func
        return decorator
    
    def run(self, host: str = None, port: int = None):
        """启动服务器"""
        run_host = host or self.host
        run_port = port or self.port
        
        print(f"Starting SimpleAPI server on {run_host}:{run_port}")
        self.app.start(host=run_host, port=run_port) 